#!/usr/bin/env python
"""

    itertools_extra.py

"""

################################################################################
#
#   itertools_extra.py
#
#################################################################################

import sys, os
from collections import defaultdict


#88888888888888888888888888888888888888888888888888888888888888888888888888888888888888888

#   Functions        


#88888888888888888888888888888888888888888888888888888888888888888888888888888888888888888
from itertools import izip
def adjacent_iter (array, reverse = False):
    """
    returns pairs of iterators to successive positions
    """
    if len(array) < 2:
        return

    # get iterators to successive positions
    if reverse:
        curr = reversed(array)
        next = reversed(array)
    else:
        curr = iter(array)
        next = iter(array)
    next.next() 
    for i, j in izip(curr, next):
        yield i, j    


        
#
#   reimplementation of
#   http://code.activestate.com/recipes/576719/
# 
def flatten_iter(l):
    try:
        if isinstance(l, str):
            yield l
        elif len(l):
            for ll in l:
                for lll in flatten_iter(ll):
                    yield lll
    except:
        yield l


#88888888888888888888888888888888888888888888888888888888888888888888888888888888888888888

#   Testing


#88888888888888888888888888888888888888888888888888888888888888888888888888888888888888888


#
#   debug code not run if called as a module
#     
if __name__ == '__main__':
    import unittest
    #       self.assertEqual(self.seq, range(10))
    #       self.assert_(element in self.seq)
    #       self.assertRaises(ValueError, random.sample, self.seq, 20)
    class Test_adjacent_iter(unittest.TestCase):

        def test_function(self):
            """
                test 
            """
            numbers = range(10)
            adjacent_list = [(i,j) for (i, j) in adjacent_iter(numbers)]
            self.assertEqual(adjacent_list, [(0, 1), (1, 2), (2, 3), (3, 4), (4, 5), (5, 6), (6, 7), (7, 8), (8, 9)])

            adjacent_list = [(i,j) for (i, j) in adjacent_iter(numbers, reverse=True)]
            self.assertEqual(adjacent_list, [(9, 8), (8, 7), (7, 6), (6, 5), (5, 4), (4, 3), (3, 2), (2, 1), (1, 0)])

    class Test_flatten_iter(unittest.TestCase):

        def test_function(self):
            """
                test 
            """
            numbers = range(10)
            nested_list = [(0, 1,2),[], [3], (set([6, 4,  5, None, 6]), [7, [8,9]]), 'test']
            flattened_list = list(flatten_iter(nested_list))
            self.assertEqual(sorted(flattened_list), [None] + range(10) + ['test'])

    if sys.argv.count("--debug"):
        sys.argv.remove("--debug")
    unittest.main()



    
